//! @Author: DengLibin
//! @Date: Create in 2024-08-05 14:02:27
//! @Description:

use image::ImageFormat;
use serde::Deserialize;
use pdfium_render::prelude::*;
use my_util_lib::file_util;


//文本及位置信息
#[derive(Deserialize, Debug)]
pub struct TextPosion {
    #[serde(rename = "box")]
    pub text_box: [[i32; 2]; 4],
    pub score: f32,
    pub text: String,
}

// 使用pdfium-render 要安装 pdfium库，下载地址：https://github.com/bblanchon/pdfium-binaries/releases/tag/chromium/6555
pub fn demo(pdf_path: &str) -> Result<(), Box<dyn std::error::Error>> {
    // 初始化 PDFium 库
    // let pdfium = Pdfium::new(Pdfium::bind_to_system_library()?);
    println!("加载pdfium库");
    // let bindings = Pdfium::bind_to_library(Pdfium::pdfium_platform_library_name_at_path(
    //     "./pdfium.dll.lib",
    // ))
    // .or_else(|_| Pdfium::bind_to_system_library())?;
    // let bindings = Pdfium::bind_to_library("./pdfium.dll")
    //     .or_else(|_| Pdfium::bind_to_library("./pdfium.so"))?;
    // let pdfium = Pdfium::new(bindings);

    let pdfium = Pdfium::default();

    println!("打开pdf:{}", pdf_path);
    // 打开 PDF 文档
    let mut document: PdfDocument<'_> = pdfium.load_pdf_from_file(pdf_path, None)?;
    println!("打开pdf成功");

    let symbol_fonts = document.fonts_mut().symbol();

    // 获取第一个页面
    // let page = document.pages().get(0)?;
    for mut page in (document.pages_mut()).iter() {
        let mut recs: Vec<PdfRect> = Vec::new();
        let objects = page.objects();

        for object in objects.iter() {
            match &object {
                //文本
                PdfPageObject::Text(text_obj) => {
                    // let text = text_obj.text();
                    let bounds_r = text_obj.bounds();
                    match bounds_r {
                        Ok(bounds) => {
                            //文本和坐标

                            // println!("Text: {}, Bounds: {:?}", text, bounds);

                            recs.push(bounds);
                        }
                        Err(err) => {
                            println!("获取文本坐标失败{}", err);
                        }
                    }
                }
                //图像
                PdfPageObject::Image(img) => {
                    let bounds_r = img.bounds();
                    match bounds_r {
                        Ok(bounds) => {
                            // 创建一个矩形
                            let rect =
                                PdfRect::new(bounds.bottom, bounds.left, bounds.top, bounds.right);
                            recs.push(rect);
                        }
                        Err(err) => {
                            println!("获取图像坐标失败{}", err);
                        }
                    }
                }
                _ => {}
            }
        }

        println!("元素数量:{}", recs.len());
        let mut index = 0_usize;

        for rect in recs {
            // 在页面上绘制文本
            let _ = page.objects_mut().create_text_object(
                PdfPoints::new(rect.left.value + 2.0),
                PdfPoints::new(rect.top.value + 1.0),
                format!("{}", index),
                symbol_fonts,
                PdfPoints::new(5.0),
            );
            // 在页面上绘制矩形
            let _ = page.objects_mut().create_path_object_rect(
                rect,
                Some(PdfColor::RED),
                Some(PdfPoints::new(1.0)),
                None,
            )?;
            index += 1;
        }
    }
    document.save_to_file("example.pdf")?;

    Ok(())
}

/// @Author: DengLibin
/// @Date: Create in 2024-08-05 13:44:54
/// @Description: 提取图片
pub fn extract_pic(pdf_path: &str, pic_dir: &str) -> Result<(), Box<dyn std::error::Error>> {
    // let bindings =
    //     Pdfium::bind_to_library(Pdfium::pdfium_platform_library_name_at_path("./pdfium.lib"))
    //         .or_else(|_| Pdfium::bind_to_system_library())?;
    // let pdfium = Pdfium::new(bindings);

    let pdfium = Pdfium::default();

    // 打开 PDF 文档
    let document = pdfium.load_pdf_from_file(pdf_path, None)?;
    if !file_util::exist(pic_dir) {
        let _ = file_util::create_dr(pic_dir);
    }

    // 获取第一个页面
    // let page = document.pages().get(0)?;
    let mut page_index = 0;
    for page in (document.pages()).iter() {
        let objects = page.objects();
        page_index += 1;
        let mut img_index = 0;
        for object in objects.iter() {
            match &object {
                //图像
                PdfPageObject::Image(img) => {
                    let img_r = img.get_processed_image(&document);
                    if let Ok(img) = img_r {
                        img_index += 1;
                        let r = img.save(format!("{}/{}_{}.png", pic_dir, page_index, img_index));
                        if let Err(err) = r {
                            println!("保存图片失败{}", err);
                        }
                    }
                }
                _ => {}
            }
        }
    }

    Ok(())
}

/// @Author: DengLibin
/// @Date: Create in 2024-08-05 13:44:54
/// @Description: 每页转图片
pub fn page2pic(pdf_path: &str, pic_dir: &str) -> Result<(), Box<dyn std::error::Error>> {
    let pdfium = Pdfium::default();

    // 打开 PDF 文档
    let document = pdfium.load_pdf_from_file(pdf_path, None)?;
    if !file_util::exist(pic_dir) {
        let _ = file_util::create_dr(pic_dir);
    }

    // 获取第一个页面
    // let page = document.pages().get(0)?;
    // let mut page_index = 0;
    // for page in (document.pages()).iter() {
    //     page_index += 1;

    //     // 渲染页面为 RGBA 像素数据
    //     let render = page.render_with_config(&PdfRenderConfig::new().set_target_width(600))?;

    //     render
    //         .as_image()
    //         .save(format!("{}/{}.png", pic_dir, page_index))?;
    // }
    let mut render_config =
        PdfRenderConfig::new().rotate_if_landscape(PdfPageRenderRotation::Degrees90, true);

    for (index, page) in document.pages().iter().enumerate() {
        let width = page.width().value;
        let height = page.height().value;
        render_config = render_config.set_target_width(width as i32 * 2);
        render_config = render_config.set_target_height(height as i32 * 2);

        page.render_with_config(&render_config)?
            .as_image() // Renders this page to an image::DynamicImage...
            .into_rgb8() // ... then converts it to an image::Image...
            .save_with_format(format!("{}/{}.jpg", pic_dir, index), ImageFormat::Jpeg) // ... and saves it to a file.
            .map_err(|_| PdfiumError::ImageError)?;
    }

    Ok(())
}

/// @Author: DengLibin
/// @Date: Create in 2024-10-09 20:04:24
/// @Description: 写入文本
pub fn add_text_demo(
    texts: &Vec<TextPosion>,
    pdf_path: &str,
    out_pdf_path: &str,
    scale: f32,
) -> Result<(), Box<dyn std::error::Error>> {
    let pdfium = Pdfium::default();

    println!("打开pdf:{}", pdf_path);
    // 打开 PDF 文档
    let mut document = pdfium.load_pdf_from_file(pdf_path, None)?;
    println!("打开pdf成功");

    // 获取第一页
    let mut page = document.pages().get(0)?;
    let page_width = page.width().value;
    let page_height = page.height().value;
    println!("page_width:{}, page_height:{}", page_width, page_height);
    // let font: PdfFontToken = document.fonts_mut().symbol();
    let font_bytes = include_bytes!("../../simfang.ttf");
    let font = document
        .fonts_mut()
        .load_true_type_from_bytes(font_bytes, true)?;
    // 创建文本对象并设置位置、大小、颜色
    for text_postion in texts {
        let height = text_postion.text_box[3][1] - text_postion.text_box[0][1];
        let height = height as f32 * scale;
        let width = text_postion.text_box[1][0] - text_postion.text_box[0][0];
        let width = width as f32 * scale;
        //计算字体大小
        let font_size = width / text_postion.text.chars().count() as f32;
        println!("字体大小:{},长度:{}", font_size, text_postion.text.chars().count());
        let mut text_object = PdfPageTextObject::new(
            &document,
            text_postion.text.as_str(),
            font,
            PdfPoints::new(font_size),
        )?;

        // 设置文本颜色 (RGB)
        text_object.set_fill_color(PdfColor::RED)?; // 红色

        let x = text_postion.text_box[0][0] as f32 * scale;
        let y = text_postion.text_box[0][1] as f32 * scale;
        //pdf原点在左下角，换算一下
        let y = page_height - y - height + 2.0f32;

        println!("x:{}, y:{}", x, y);

        // 移动文本对象到指定位置 (x, y)
        text_object.translate(PdfPoints::new(x), PdfPoints::new(y))?; // X 和 Y 坐标，移动文本对象到页面中的位置

        page.objects_mut().add_text_object(text_object)?;
    }
    document.save_to_file(out_pdf_path)?;
    Ok(())
}

/// @Author: DengLibin
/// @Date: Create in 2025-08-11 10:17:24
/// @Description: 提取pdf的某几页到新的pdf
pub fn extract_pages(pdf_path: &str, page_nums: &Vec<u16>, out_pdf_path: &str) -> Result<(), Box<dyn std::error::Error>> {

    let pdfium = Pdfium::default();

    // 打开源 PDF
    let doc = pdfium.load_pdf_from_file(pdf_path, None)?;

    // 创建一个新文档
    let mut new_doc = pdfium.create_new_pdf()?;

    let mut dest_page = 0_u16;
    for idx in page_nums {
        // let page = doc.pages().get(()?;
        new_doc.pages_mut().copy_page_from_document(&doc, (*idx -1), dest_page)?;
        dest_page += 1;
    }

    new_doc.save_to_file(out_pdf_path)?;
    Ok(())
}